除了使用MicroPython 來開發應用程式外,其實我們也可以使用 Arduino IDE 來開發應用程式。不過要注意的是,Arduino IDE 主要是使用 C/C++ 語言來開發。接下來我們來教大家如何按照玩學機手冊裡面的資訊,安裝必備軟體,讓我們也可以使用 C/C++ 語言來開發程式。
3. 選擇開發版為「ESP32 Dev Module 」,連接埠選擇「COM17 Serial Port(USB)」(本例使用的玩學機,作業系統辨識到的COM Port 是 17,請按照您電腦的實際情況,選擇正確的 COM Port)。
玩學運算公司開發了一個 VGA 擴充模組,可以讓您使用 Arduino IDE 開發能輸出玩學機畫面到螢幕上的程式。您只要執行「okesp-160x128-galaxian-lcd-sync-vga-v1r2.ino」程式,將其燒錄到玩學機。把VGA線接到螢幕,就會發現小蜜蜂遊戲的畫面已經同步到電腦螢幕上。這樣玩起來就更舒服。
您可以試著閱讀程式碼,就會發現這個小蜜蜂遊戲是由 C 語言實作的。這也是 MicroPyhon 版小蜜蜂的基礎(繪圖引擎)。讀者可以試著修改小蜜蜂的原始碼,就能了解如何在 Arduino 環境中開發小遊戲。
我們也期待玩學運算公司能早一點將 VGA 模組的驅動程式移植到 MicroPython 環境,這樣我們就能開發更多能在電腦螢幕上玩的遊戲或是應用程式。讓 WiFiBoy Python 玩學機變成一台能真正用在生活中的應用工具。
遊戲實際運作情況,可以參考下列影片。
https://www.youtube.com/watch?v=Kz_rWXI6N3I
// WiFiBoy LCD+VGA Examples
//
// cc by-sa 4.0 license
// bitluni & dereklai
//include libraries
#include <ESP32Lib.h>
#include <Ressources/CodePage437_8x8.h>
#include <wifiboy_lib.h>
#include <math.h>
#include "sprites.h"
extern uint8_t *wb_buf8;
VGA6Bit vga;
///////////////////////////////////////
// VGA Pin Configuration
const int redPins[] = {2,19};
const int greenPins[] = {5,18};
const int bluePins[] = {21,22};
const int hsyncPin = 23;
const int vsyncPin = 26;
char colors[]={ 0x03,0x0b,0x07,0x0f,0x0d,0x0e,0x0c,0x24,0x18,0x30,0x32,0x31,0x33,0x13,0x23,0x03};
//////////////////////////////////////
uint8_t m_x[100];
uint16_t m_y[100];
uint8_t m_v[100];
uint16_t m_c[100];
int xx=60, yy, shooting=0, ct=0, dx=1, dir=2, spn[18], hs=0, sc=0, k=0
void blit_str256(char *str, int x, int y)
{
int cc;
for(int i=0; i<strlen(str); i++) {
if (str[i]>=' '&& str[i]<='~') {
cc=str[i]-' ';
wb_blitBuf8(8*(cc%16),8*(cc/16),128, x+i*8, y, 8, 8, (uint8_t *)sprites);
}
}
}
void blit_num256(uint16_t num, uint16_t x, uint16_t y)
{
uint16_t d[5];
d[0]=num/10000;
d[1]=(num-d[0]*10000)/1000;
d[2]=(num-d[0]*10000-d[1]*1000)/100;
d[3]=(num-d[0]*10000-d[1]*1000-d[2]*100)/10;
d[4]=num-d[0]*10000-d[1]*1000-d[2]*100-d[3]/10;
for(int i=0; i<5; i++) {
wb_blitBuf8(d[i]*8, 8, 128, x+i*8, y, 8, 8, (uint8_t *)sprites);
}
}
////////////////////////////
// Beep Sounds
void setup_sound()
{
pinMode(17, OUTPUT);
digitalWrite(17,1); // sound on for buzzer
pinMode(25, OUTPUT);
}
void beeper(int freq, int time)
{
for(int i=0;i<time;i++) {
digitalWrite(25,1);
for(int j=0;j<freq; j++) delayMicroseconds(10);
digitalWrite(25,0);
for(int j=0;j<freq; j++) delayMicroseconds(10);
}
}
////////////////////////////
void setup()
{
vga.setFrameBufferCount(2);
vga.init(vga.MODE200x150, redPins, greenPins, bluePins, hsyncPin, vsyncPin);
vga.setFont(CodePage437_8x8);
wb_init(3);
wb_initBuf8();
wb_clearBuf8();
for(int i=0; i<256; i++)
wb_setPal8(i, wb_color565(pals[i][0],pals[i][1],pals[i][2]));
wb_blitBuf8(0, 0, 128, 0, 0, 128, 128, (uint8_t *)sprites);
wb_blit8();
for(int i=0; i<100; i++) {
m_x[i]=random(0,240);
m_y[i]=random(0,320);
m_v[i]=random(2,5);
m_c[i]=wb_rand(10)+54;
}
for(int i=0; i<18; i++) spn[i]=1;
setup_sound();
}
unsigned char c2c[64]={
0, 32, 16, 48, 2, 34, 18, 50, 1, 33, 17, 49, 3, 35, 19, 51,
8, 40, 24, 56, 10, 42, 26, 58, 9, 41, 25, 57, 11, 43, 27, 59,
4, 36, 20, 52, 6, 38, 22, 54, 5, 37, 21, 53, 7, 39, 23, 55, 12,
44, 28, 60, 14, 46, 30, 62, 13, 45, 29, 61, 15, 47, 31, 63
};
void loop()
{
int i, j, sx, sy;
wb_clearBuf8();
for(i=0; i<100; i++) {
wb_setBuf8(m_x[i]+m_y[i]*240, m_c[i]);
m_y[i] += m_v[i];
if (m_y[i]>=320) m_y[i]-=320;
}
if (((wb_getkey()&4)==4) && (xx<143)) xx += 2;
if (((wb_getkey()&8)==8) && (xx>2)) xx -= 2;
// fighter
wb_blitBuf8(24, 48, 128, xx, 112, 16, 16, (uint8_t *)sprites);
if (((wb_getkey()&1)==1) && (shooting==0)) {
yy=110; shooting=1;
beeper(400,5);
//beeper(20,50); beeper(12,50);
//beeper(500,5);
}
if ((wb_getkey()&2)==2) { for(i=0; i<18; i++) spn[i]=1; sc=0; k=0; }
// bullet
if (shooting==1) {
yy-=5; if (yy<0) { yy=112; shooting=0;}
wb_blitBuf8(4, 51, 128, xx+5, yy, 3, 4, (uint8_t *)sprites);
} else wb_blitBuf8(4, 51, 128, xx+5, 112, 3,4,(uint8_t *)sprites);
// aliens
ct += 1;
if ((ct%4)==0) {
dx += dir;
if (dx>64) { dir=-2; dx=64; }
if (dx<1) { dir=2; dx=1; }
}
for(i=32; i<97; i+=48)
wb_blitBuf8(0, 80, 128, dx+i-16, 12, 16,16, (uint8_t *)sprites);
for(i=0; i<18; i++) {
sx = dx+(i%6)*16;
sy = (i/6)*16+30;
if (spn[i]==1) {
if ((ct+i)%40<20) wb_blitBuf8(0, 64, 128, sx, sy, 16,16, (uint8_t *)sprites);
else wb_blitBuf8(16, 64, 128, sx, sy, 16,16, (uint8_t *)sprites);
if ((yy-sy>0) && (yy-sy<16) && (xx+5-sx>0) && (xx+5-sx<13)) {
spn[i]=20; yy = 0; sc+=100;
//beeper(10,100); beeper(5,50); beeper(2,50); beeper(1,50);
//beeper(400,15);
beeper(20,50); beeper(12,50);
// beep(900); delay(10); beep(600); delay(10); beep(800); delay(10); beepoff();
}
} else if (spn[i]>9) {
wb_blitBuf8(48, 51, 128, sx+3, sy+3, 8,8, (uint8_t *)sprites);
spn[i]-=1;
} else if (spn[i]>3) {
wb_blitBuf8(56, 48, 128, sx, sy, 16,16, (uint8_t *)sprites);
spn[i]-=1;
} else if (spn[i]==3) {
spn[i]=2;
if (++k==18) { k=0; for(j=0; j<18; j++) spn[j]=1; }
}
}
blit_str256("WiFiBoy LCD+VGA", 20, 90);
blit_str256("H:", 92,0);
blit_str256("S:", 12,0);
blit_num256(sc, 28, 0);
if (sc>hs) hs=sc;
blit_num256(hs, 108, 0);
for(int i=0; i<128; i++) {
for(int j=0; j<160; j++) {
vga.dotFast(j+20, i+11, c2c[wb_buf8[i*160+j]]);
}
}
vga.show();
wb_blit8();
delay(5);
}